import time

import pandas as pd

from config import BaseConfig
from db.models import StockFundsHolder, IndustryGrowthList, IndustryStockList, ConceptStockList, ConceptRankingList
from service.requests.spider_request import request_get_url
from utils.util import CommonUtil, StockTool

"""
东方财富网 数据接口
http://quote.eastmoney.com/sz002497.html
"""
# 行情url
quotation_url = "http://push2.eastmoney.com/api/qt/stock/get"
kline_url = 'http://90.push2his.eastmoney.com/api/qt/stock/kline/get'
all_kline_url = 'https://push2his.eastmoney.com/api/qt/stock/kline/get?fields1=f1%2Cf2%2Cf3%2Cf4%2Cf5%2Cf6&fields2=f51%2Cf52%2Cf53%2Cf54%2Cf55%2Cf56%2Cf57%2Cf58%2Cf59%2Cf60%2Cf61&ut=7eea3edcaed734bea9cbfc24409ed989&klt=101&fqt=1&secid={0}&beg=0&end=20500000&_=1633082201530'
stock_rank_url = 'https://push2.eastmoney.com/api/qt/clist/get'
# 行业排行榜
industry_growth_url = 'https://47.push2.eastmoney.com/api/qt/clist/get'
# 概念排行榜
concept_ranking_url = 'http://push2.eastmoney.com/api/qt/clist/get'

# 行业内股票排行榜
stock_url = 'https://push2.eastmoney.com/api/qt/clist/get'

industry_blacklist = BaseConfig.CUSTOM_INDUSTRY_BLACK


# def add_context(func):
#     @wraps(func)
#     def do_job(*args, **kwargs):
#         app = Flask(__name__)
#         app.app_context().push()
#         result = func(*args,**kwargs)
#         return result
#     return do_job


class Eastmoney:
    @staticmethod
    def get_stock_secid(stock_code=''):
        """
        获取股票的secid
        :return:
        """
        jys = StockTool.code2MarketNum(stock_code)
        if jys:
            return jys + '.' + stock_code
        return None

    @staticmethod
    def get_realtime_quotes(stock_code,
                            field='f43,f44,f45,f46,f47,f48,f50,f57,f58,f60,f71,f86,f127,f128,f137,f161,f162,f167,f168,f169,f170'):
        """
        获取股票的“行情报价”
        https://php-note.com/2094.html
        http://push2.eastmoney.com/api/qt/stock/get?ut=fa5fd1943c7b386f172d6893dbfba10b&invt=2&fltt=2&fields=f43,f57,f58,f169,f170,f46,f44,f51,f168,f47,f164,f163,f116,f60,f45,f52,f50,f48,f167,f117,f71,f161,f49,f530,f135,f136,f137,f138,f139,f141,f142,f144,f145,f147,f148,f140,f143,f146,f149,f55,f62,f162,f92,f173,f104,f105,f84,f85,f183,f184,f185,f186,f187,f188,f189,f190,f191,f192,f107,f111,f86,f177,f78,f110,f262,f263,f264,f267,f268,f250,f251,f252,f253,f254,f255,f256,f257,f258,f266,f269,f270,f271,f273,f274,f275,f127,f199,f128,f193,f196,f194,f195,f197,f80,f280,f281,f282,f284,f285,f286,f287,f292&secid=0.002497&_=1632995105757
        :param stock_code: 股票代码
        :param field: 查询字段
                     【特别注意】如果要返回“五档交易数据”，就必须传入字段 f530
                    "f43": 33.1,            // 最新价(元)
                    "f44": 33.55,           // 最高价(元)
                    "f45": 31.22,           // 最低价(元)
                    "f46": 31.26,           // 开盘价(元)
                    "f47": 705757,          // 总手数(手)
                    "f48": 2303402672,      // 总金额(元)
                    "f49": 371817,          // 外盘(手) 买入
                    "f50": 0.98,            // 量比(%)
                    "f57": "002497",        // 股票代码
                    "f58": "雅化集团",      // 股票名称
                    "f60": 31.05,           // 昨天收盘价(元)
                    "f71": 32.64,           // 均价(元)
                    "f86": 1632987243,     // 分时时间戳，如：2021-09-30 15:34:03
                    "f127": "化工行业",     // 所属行业
                    "f128": "四川板块",     // 所属版块
                    "f137": 182462816,      // 今日主力净流入(元)
                    "f161": 333940,         // 内盘(手) 卖出
                    "f162": 57.78,          // 市盈率(动)
                    "f167": 6.71,           // 市净率(%)
                    "f168": 6.77,           // 换手率(%)
                    "f169": 2.05,           // 涨跌
                    "f170": 6.6,            // 涨跌幅(%)

                    "f173": 6.09,           // ROE
                    "f183": 2124437269.36,      // 【公司核心数据】总营收(元)
                    "f184": 64.353693337,       // 【公司核心数据】总营收.同比(%)
                    "f185": 151.009110738454,   // 【公司核心数据】净利润.同比(%)
                    "f186": 32.6366068422,      // 【公司核心数据】毛利率(%)
                    "f187": 16.726336094,       // 【公司核心数据】净利率(%)
                    "f188": 21.4630459073,      // 【公司核心数据】负债率(%)
        """
        params = {
            'invt': 2,
            'fltt': 2,
            'secid': Eastmoney.get_stock_secid(stock_code),
            'ut': 'fa5fd1943c7b386f172d6893dbfba10b',
            'fields': field,
            '_': int(round(time.time() * 1000))

        }
        try:
            page_json = request_get_url(quotation_url, params)
            page_data = page_json.get('data')
            if page_data:
                fund = StockFundsHolder()
                setattr(fund, 'stock_code', page_data.get('f57'))
                setattr(fund, 'stock_name', page_data.get('f58'))
                setattr(fund, 'open', page_data.get('f46'))
                setattr(fund, 'now', page_data.get('f43'))
                setattr(fund, 'high', page_data.get('f44'))
                setattr(fund, 'low', page_data.get('f45'))
                setattr(fund, 'average', page_data.get('f71'))
                setattr(fund, 'preclose', page_data.get('f60'))
                setattr(fund, 'volume', page_data.get('f47'))
                setattr(fund, 'amount', page_data.get('f48'))
                # setattr(fund,'tradestatus',page_data.get(''))
                setattr(fund, 'pctChg', page_data.get('f170'))
                setattr(fund, 'turn', page_data.get('f168'))
                setattr(fund, 'inner', page_data.get('f161'))
                setattr(fund, 'outer', page_data.get('f49'))
                setattr(fund, 'volume_ratio', page_data.get('f50'))
                setattr(fund, 'PE', page_data.get('f162'))
                setattr(fund, 'PB', page_data.get('f167'))
                setattr(fund, 'main_net_inflow', page_data.get('f137'))
                setattr(fund, 'create_time', CommonUtil.timestamp2Date(page_data.get('f86')))
                # setattr(fund,'',page_data.get(''))

            return fund

        except Exception as e:
            print(e)
            return None

    @staticmethod
    def get_company_fundamentals(stock_code, field='f57,f58,f127,f173,f183,f184,f185,f186,f187,f188'):
        """
        公司基本面
        https://php-note.com/2094.html
        http://push2.eastmoney.com/api/qt/stock/get?ut=fa5fd1943c7b386f172d6893dbfba10b&invt=2&fltt=2&fields=f43,f57,f58,f169,f170,f46,f44,f51,f168,f47,f164,f163,f116,f60,f45,f52,f50,f48,f167,f117,f71,f161,f49,f530,f135,f136,f137,f138,f139,f141,f142,f144,f145,f147,f148,f140,f143,f146,f149,f55,f62,f162,f92,f173,f104,f105,f84,f85,f183,f184,f185,f186,f187,f188,f189,f190,f191,f192,f107,f111,f86,f177,f78,f110,f262,f263,f264,f267,f268,f250,f251,f252,f253,f254,f255,f256,f257,f258,f266,f269,f270,f271,f273,f274,f275,f127,f199,f128,f193,f196,f194,f195,f197,f80,f280,f281,f282,f284,f285,f286,f287,f292&secid=0.002497&_=1632995105757
        :param stock_code: 股票代码
        :param field: 查询字段
                     【特别注意】如果要返回“五档交易数据”，就必须传入字段 f530
                    "f43": 33.1,            // 最新价(元)
                    "f44": 33.55,           // 最高价(元)
                    "f45": 31.22,           // 最低价(元)
                    "f46": 31.26,           // 开盘价(元)
                    "f47": 705757,          // 总手数(手)
                    "f48": 2303402672,      // 总金额(元)
                    "f49": 371817,          // 外盘(手) 买入
                    "f50": 0.98,            // 量比(%)
                    "f57": "002497",        // 股票代码
                    "f58": "雅化集团",      // 股票名称
                    "f60": 31.05,           // 昨天收盘价(元)
                    "f71": 32.64,           // 均价(元)
                    "f86": 1632987243,     // 分时时间戳，如：2021-09-30 15:34:03
                    "f127": "化工行业",     // 所属行业
                    "f128": "四川板块",     // 所属版块
                    "f137": 182462816,      // 今日主力净流入(元)
                    "f161": 333940,         // 内盘(手) 卖出
                    "f162": 57.78,          // 市盈率(动)
                    "f167": 6.71,           // 市净率(%)
                    "f168": 6.77,           // 换手率(%)
                    "f169": 2.05,           // 涨跌
                    "f170": 6.6,            // 涨跌幅(%)

                    "f173": 6.09,           // ROE
                    "f183": 2124437269.36,      // 【公司核心数据】总营收(元)
                    "f184": 64.353693337,       // 【公司核心数据】总营收.同比(%)
                    "f185": 151.009110738454,   // 【公司核心数据】净利润.同比(%)
                    "f186": 32.6366068422,      // 【公司核心数据】毛利率(%)
                    "f187": 16.726336094,       // 【公司核心数据】净利率(%)
                    "f188": 21.4630459073,      // 【公司核心数据】负债率(%)
        """
        params = {
            'invt': 2,
            'fltt': 2,
            'secid': Eastmoney.get_stock_secid(stock_code),
            'ut': 'fa5fd1943c7b386f172d6893dbfba10b',
            'fields': field,
            '_': int(round(time.time() * 1000))

        }
        try:
            page_json = request_get_url(quotation_url, params)
            page_data = page_json.get('data')

            return page_data

        except Exception as e:
            print(e)
            return None

    @staticmethod
    def get_all_klines(stock_code=''):
        '''
        历史所有的K线
        '''
        try:
            page_json = request_get_url(all_kline_url.format(Eastmoney.get_stock_secid(stock_code)), params=None)
            page_array = page_json.get('data').get('klines')
            pd_data_frame = pd.DataFrame(page_array)
            pd_data_frame = pd_data_frame[0].str.split(',', expand=True)
            pd_data_frame.columns = ['date', 'open', 'close', 'high', 'low', 'volume', 'amount', '振幅', 'pctChg', '涨跌',
                                     'turn']
            pd_data_frame.set_index('date',inplace=True)
            return pd_data_frame

        except Exception as e:
            print(e)
            return None

    @staticmethod
    def get_klines(stock_code, days=120):
        '''
        日K线
        :param stock_code:
        :return:
        '''
        if not stock_code:
            return pd.DataFrame()
        params = {
            'lmt': days,
            'klt': 101,
            'fqt': '1',
            'end': '20500101',
            'secid': Eastmoney.get_stock_secid(stock_code),
            'ut': 'fa5fd1943c7b386f172d6893dbfba10b',
            'fields1': 'f1,f2,f3,f4,f5,f6',
            'fields2': 'f51,f52,f53,f54,f55,f56,f57,f58,f59,f60,f61',
            '_': int(round(time.time() * 1000))

        }
        page_json = request_get_url(kline_url, params)
        page_array = page_json.get('data').get('klines')
        pd_data_frame = pd.DataFrame(page_array)
        pd_data_frame = pd_data_frame[0].str.split(',', expand=True)
        pd_data_frame.columns = ['date', 'open', 'close', 'high', 'low', 'volume', 'amount', '振幅', 'pctChg', '涨跌',
                                 'turn']
        pd.to_datetime(pd_data_frame['date'])
        pd_data_frame.set_index('date', inplace=True)
        pd_data_frame.index = pd.DatetimeIndex(pd_data_frame.index)
        return pd_data_frame

    @staticmethod
    def get_industry_growth_list(pageNum=1, pageSize=10):

        params = {
            'pn': pageNum,
            'pz': pageSize,
            'po': '1',
            'np': '1',
            'ut': 'bd1d9ddb04089700cf9c27f6f7426281',
            'fltt': '2',
            'invt': '2',
            'wbp2u': '3529094263470942|0|0|0|web',
            'fid': 'f3',
            'fs': 'm:90+t:2+f:!50',
            'fields': 'f2,f3,f8,f10,f12,f14,f33,f62,f128,f104,f105,f140,f124'

        }
        page_json = request_get_url(industry_growth_url, params)
        page_array = page_json.get('data').get('diff')

        industryGrowthLists = []
        if page_array:
            for index, klines in enumerate(page_array, start=1):
                # 最新价格
                now_price = klines['f2']
                # 涨跌幅
                pctChg = klines['f3']
                # 换手率
                turn = klines['f8']
                # 量比
                volume_ratio = klines['f10']
                # 板块编码
                industry_code = klines['f12']
                # 板块名称
                industry_name = klines['f14']
                # 资金净流入
                main_net_inflow = klines['f62']

                if main_net_inflow < 0:
                    break
                # 领涨股票名称
                leading_stock_name = klines['f128']
                # 领涨股票代码
                leading_stock_code = klines['f140']
                # 上涨家数
                rising_nums = klines['f104']
                # 下跌家数
                decliner_nums = klines['f105']

                time_stamp = klines['f124']

                timeArray = time.localtime(time_stamp)
                otherStyleTime = CommonUtil.timestamp2Date(time_stamp)

                interval = CommonUtil.get_time_interval(timeArray.tm_hour, timeArray.tm_min)

                industryGrowthList = IndustryGrowthList()
                setattr(industryGrowthList, 'industry_name', industry_name)
                setattr(industryGrowthList, 'industry_code', industry_code)
                setattr(industryGrowthList, 'now_price', now_price)
                setattr(industryGrowthList, 'volume_ratio', volume_ratio)
                setattr(industryGrowthList, 'pctChg', pctChg)
                setattr(industryGrowthList, 'turn', turn)
                setattr(industryGrowthList, 'rising_nums', rising_nums)
                setattr(industryGrowthList, 'decliner_nums', decliner_nums)
                setattr(industryGrowthList, 'leading_stock_code', leading_stock_code)
                setattr(industryGrowthList, 'leading_stock_name', leading_stock_name)
                setattr(industryGrowthList, 'main_net_inflow', main_net_inflow)
                setattr(industryGrowthList, 'create_time', otherStyleTime)
                setattr(industryGrowthList, 'time_interval', interval)
                industryGrowthLists.append(industryGrowthList)

        return industryGrowthLists

    @staticmethod
    def get_concept_ranking_list(pageNum=1, pageSize=30):
        params = {
            'fid': 'f62',
            'po': '1',
            'pn': pageNum,
            'pz': pageSize,
            'np': '1',
            'ut': 'b2884a393a59ad64002292a3e90d46a5',
            'fltt': '2',
            'invt': '2',
            'fs': 'm:90+t:3',
            'fields': 'f12,f14,f2,f3,f8,f10,f62,f204,f205,f124,f104,f105,f106'
        }
        page_json = request_get_url(concept_ranking_url, params)
        page_array = page_json.get('data').get('diff')
        concept_ranking_list=[]
        if page_array:
            for index, klines in enumerate(page_array, start=1):
                # 最新价格
                now_price = klines['f2']
                # 涨跌幅
                pctChg = klines['f3']
                # 换手率
                turn = klines['f8']
                # 量比
                volume_ratio = klines['f10']
                # 概念编码
                concept_code = klines['f12']
                # 概念名称
                concept_name = klines['f14']
                # 资金净流入
                main_net_inflow = klines['f62']

                if main_net_inflow < 0:
                    break
                # 上涨家数
                rising_nums = klines['f104']
                # 下跌家数
                decliner_nums = klines['f105']
                # 平盘数
                flat_nums = klines['f106']

                # 领涨股票名称
                leading_stock_name = klines['f204']
                # 领涨股票代码
                leading_stock_code = klines['f205']

                # 时间戳
                time_stamp = klines['f124']

                timeArray = time.localtime(time_stamp)
                otherStyleTime = CommonUtil.timestamp2Date(time_stamp)

                interval = CommonUtil.get_time_interval(timeArray.tm_hour, timeArray.tm_min)

                industryGrowthList = ConceptRankingList()
                setattr(industryGrowthList, 'concept_name', concept_name)
                setattr(industryGrowthList, 'concept_code', concept_code)
                setattr(industryGrowthList, 'now_price', now_price)
                setattr(industryGrowthList, 'volume_ratio', volume_ratio)
                setattr(industryGrowthList, 'pctChg', pctChg)
                setattr(industryGrowthList, 'turn', turn)
                setattr(industryGrowthList, 'rising_nums', rising_nums)
                setattr(industryGrowthList, 'decliner_nums', decliner_nums)
                setattr(industryGrowthList, 'flat_nums', flat_nums)
                setattr(industryGrowthList, 'leading_stock_code', leading_stock_code)
                setattr(industryGrowthList, 'leading_stock_name', leading_stock_name)
                setattr(industryGrowthList, 'main_net_inflow', main_net_inflow)
                setattr(industryGrowthList, 'create_time', otherStyleTime)
                setattr(industryGrowthList, 'create_date', otherStyleTime)
                setattr(industryGrowthList, 'time_interval', interval)
                concept_ranking_list.append(industryGrowthList)

        return concept_ranking_list

    @staticmethod
    def get_stock_rank(industry_code, industry_name, time_interval, create_time):
        '''
        过滤股票保存进股票池
        1. 黑名单pass
        2. 股价<7 pass
        3. 股票涨幅负的 pass
        4. 股票涨幅<行业涨幅 pass
        5. 资金净流出的 pass
        :param industry_code: 行业编码
        :param industry_name: 行业名称
        :param industry_pctChg: 行业涨幅榜
        :param time_interval: 时间区间
        :param create_time: 创建时间
        :return:
        '''
        params = {
            'fid': 'f62',
            'pz': '20',
            'po': '1',
            'np': '1',
            'pn': '1',
            'ut': 'b2884a393a59ad64002292a3e90d46a5',
            'fltt': '2',
            'invt': '2',
            'wbp2u': '3529094263470942|0|0|0|web',
            'fid': 'f3',
            'fs': 'b:' + industry_code,
            'fields': 'f12,f14,f2,f3,f62,f124'

        }
        page_json = request_get_url(stock_url, params)
        page_array = page_json.get('data').get('diff')

        stock_lists = []
        if page_array:
            for klines in page_array:
                stock_name = klines['f14']
                stock_code = klines['f12']
                now_price = klines['f2']
                pctChg = klines['f3']
                main_net_inflow = klines['f62']

                stock_list = IndustryStockList()
                setattr(stock_list, 'industry_code', industry_code)  # '板块名称'
                setattr(stock_list, 'industry_name', industry_name)
                setattr(stock_list, 'stock_code', stock_code)
                setattr(stock_list, 'stock_name', stock_name)
                setattr(stock_list, 'now_price', now_price)
                setattr(stock_list, 'pctChg', pctChg)
                setattr(stock_list, 'main_net_inflow', main_net_inflow)
                setattr(stock_list, 'create_time', create_time)
                setattr(stock_list, 'time_interval', time_interval)
                stock_lists.append(stock_list)

        return stock_lists

    @staticmethod
    def get_concept_stock_rank(concept_code, concept_name, time_interval, create_time):
        '''
        过滤股票保存进股票池
        1. 黑名单pass
        2. 股价<7 pass
        3. 股票涨幅负的 pass
        4. 股票涨幅<行业涨幅 pass
        5. 资金净流出的 pass
        :param industry_code: 行业编码
        :param industry_name: 行业名称
        :param industry_pctChg: 行业涨幅榜
        :param time_interval: 时间区间
        :param create_time: 创建时间
        :return:
        '''
        params = {
            'fid': 'f62',
            'pz': '20',
            'po': '1',
            'np': '1',
            'pn': '1',
            'ut': 'b2884a393a59ad64002292a3e90d46a5',
            'fltt': '2',
            'invt': '2',
            'wbp2u': '|0|0|0|web',
            'fs': 'b:' + concept_code,
            'fields': 'f12,f14,f2,f3,f62,f124',
            '_': int(round(time.time() * 1000))

        }
        page_json = request_get_url(stock_url, params)
        page_array = page_json.get('data').get('diff')

        stock_lists = []
        if page_array:
            for klines in page_array:
                stock_name = klines['f14']
                stock_code = klines['f12']
                now_price = klines['f2']
                pctChg = klines['f3']
                main_net_inflow = klines['f62']

                stock_list = ConceptStockList()
                setattr(stock_list, 'concept_code', concept_code)  # '板块名称'
                setattr(stock_list, 'concept_name', concept_name)
                setattr(stock_list, 'stock_code', stock_code)
                setattr(stock_list, 'stock_name', stock_name)
                setattr(stock_list, 'now_price', now_price)
                setattr(stock_list, 'pctChg', pctChg)
                setattr(stock_list, 'main_net_inflow', main_net_inflow)
                setattr(stock_list, 'create_time', create_time)
                setattr(stock_list, 'create_date', create_time)
                setattr(stock_list, 'time_interval', time_interval)
                stock_lists.append(stock_list)

        return stock_lists



if __name__ == '__main__':
    # ranking_list = Eastmoney.get_concept_ranking_list()
    stock_pd = Eastmoney.get_all_klines("000868")
    stock_pd.to_csv('datas/000868.csv')
